<?php

namespace Modules\Asset\Entities;

use Illuminate\Support\Facades\DB;
use Modules\Core\Entities\BaseEntity as Model;
use ThrowException;
use Setting;

use Modules\Asset\Entities\Resale;

use Modules\Order\Traits\Skuable;

use Asset;

// 福袋资产
class PackageSku extends Model
{
    use Skuable;

    protected $guarded = [];
    protected $table = 'package_skus';
    static public $resourceName = '';
    public $skipReduceStock = true;    // 使用此作为sku下订单时跳过减库存步骤

    protected $appends = ['union_status', 'source_type_text', 'union_status_text', 'sku_type_text', 'activity_type_text', 'sid', 'node_type_text', 'is_presell'];

    protected $casts = [
        'options' => 'json',
        'open_indexs' => 'json',
        'assets' => 'json',
        'reward' => 'json'
    ];

    public function getType($type) 
    {
        $map = [
            'base_sku_type' => 'package_sku',
            'node_type' => $this->node_type
        ];

        return @$map[$type];
    }

    public function getSourceTypeTextAttribute()
    {
        $map = [
            1 => '开奖所得',
            2 => '转售所得',
            3 => '抽奖所得',
        ];

        return @$map[$this->source_type] ?: 'unknow';
    }

    public function getUnionStatusAttribute()
    {
        $map = [
            1 => 'pending',
            2 => 'picked',
            3 => 'return_saled',
            4 => 'resaled',
            5 => 'resale_pending',
            6 => 'exchanged',
            7 => 'locked'    // 保险箱中
        ];

        return @$map[$this->status ?: 1] ?: 'unknow';
    }

    public function getUnionStatusTextAttribute()
    {
        $map = [
            'pending' => '待处理',
            'picked' => '已提货',
            'return_saled' => '已返售',
            'resaled' => '已转让',
            'resale_pending' => '转售中',
            'exchanged' => '已置换',
            'locked' => '锁定中',
        ];

        return @v($map[$this->union_status], '未知状态');
    }

    public function getIsPresellAttribute()
    {
        return $this->presell_date &&  ($this->presell_date > date('Y-m-d'));
    }

    // public function getActivityTypeTextAttribute()
    // {
    //     $map = [
    //         'box' => '盲盒',
    //         'yifanshang' => '一番赏',
    //         'fudai' => '福袋',
    //         'egg_lottery' => '扭蛋机',
    //         'lottery' => '抽奖',
    //     ];

    //     return @v($map[$this->activity_type], '');
    // }

    public function getSidAttribute()
    {
        return 'S' . (1111 + $this->id);
    }

    // 所属支付订单
    public function pay_order()
    {
        return $this->belongsTo('\Modules\Order\Entities\BaseOrder', 'pay_order_id');
    }

    // 基础sku
    public function base_sku()
    {
        $classMap = [
            'yifanshang' => '\Modules\Activity\Entities\YiFanShang\Sku',
            'fudai' => '\Modules\Activity\Entities\Fudai\Sku',
            'box' => '\Modules\Box\Entities\BoxSku',
            'lottery' => '\Modules\Activity\Entities\Lottery\Sku',
            'egg_lottery' => '\Modules\Activity\Entities\EggLottery\Sku',
            'rotate_lottery' => '\Modules\Activity\Entities\RotateLottery\Sku',
            'zhuli' => '\Modules\Activity\Entities\Zhuli\Sku',
            'product' => '\Modules\Product\Entities\Sku',
            'jika' => '\Modules\Activity\Entities\Jika\Sku',
            'choushang' => '\Modules\Activity\Entities\Choushang\Sku',
            'leitai' => '\Modules\Activity\Entities\Leitai\Sku',
            'jifen' => '\Modules\Activity\Entities\Jifen\Sku',
        ];

        if (!@$classMap[$this->node_type]) {
            return NULL;
        }

        return $this->belongsTo($classMap[$this->node_type], 'sku_id');
    }

    // 所属packagesku
    public function from_package_sku()
    {
        return $this->belongsTo('\Modules\Asset\Entities\PackageSku', 'from_package_sku_id');
    }

    // 所属发货订单
    public function pick_order()
    {
        return $this->belongsTo('\Modules\Asset\Entities\PackageOrder', 'pick_order_id');
    }

    // 所属转售
    public function resale()
    {
        // return $this->hasOne('\Modules\Asset\Entities\Resale', 'package_sku_id');
        return $this->belongsTo('\Modules\Asset\Entities\Resale', 'resale_id');
    }

    // 所属商品
    public function product()
    {
        return $this->belongsTo('\Modules\Product\Entities\Product', 'product_id');
    }

    // 所属用户
    public function user()
    {
        return $this->belongsTo('\Modules\User\Entities\User', 'user_id');
    }

    // 所属活动
    // public function activity()
    // {
    //     $class = config('activity.map')[$this->activity_type];
    //     return $this->belongsTo($class, 'activity_id');
    // }

    public function scopeSearch($query, $key)
    {

        $query = $query->where('title', 'like', '%'.$key.'%');

        if ($key[0] === 'S') {
            $sid = intVal(substr($key, 1)) - 1111;
            $query->orWhere('id', $sid);
        }

        $query->orWhereHas('user', function ($q) use ($key) {
            return $q->where('name', 'like', '%'.$key.'%')->orWhere('phone', 'like', $key .'%');
        });

        return $query;
    }

    public function scopeBelongUser($query, $user)
    {
        return $query->where('user_id', $user->id);
    }

    public function scopeTag($query, $tag)
    {
        if ($tag === 'free_order') {
            return $query->where('free_order_total', '>', 1);
        }
        elseif ($tag === 'all') {
            return $query;
        }
        else {
            return $query->where('sku_id', intVal($tag));
            // return $query->where('')
        }
    }

    // 筛选所有可以返售的sku
    public function scopeReturnSaleable($query)
    {
        return $query->where('is_return_saleable', 1)->status('pending');
    }

    // 状态筛选
    public function scopeStatus($query, $status)
    {
        // 部分客户端需要用到此种状态
        if ($status === 'client_display') {
            return $query->where('status', 1)->orWhere('status', 5);
        }

        $map = [
            'pending' => [
                'status' => 1
            ],
            'picked'  => [
                'status' => 2
            ],
            'return_saled' => [
                'status' => 3
            ],
            'resaled' => [
                'status' => 4
            ],
            'resale_pending' => [
                'status' =>  5
            ],
            'exchanged' => [
                'status' => 6
            ],
            'locked' => [
                'status' => 7
            ]
        ];

        $where = @$map[$status] ?: [];

        return $query->where($where);
    }

    // 使用sku初始化
    static public function initWith($package, $skuMap, $user, $order) 
    {
    	$sku = $skuMap['skuable'];
    	$total = $skuMap['total'];
        $freeOrderTotal = @$skuMap['free_order_total'] ?: 0; 

    	$info = [
    		'uuid' => uniqid(),
    		'user_id' => $user->id,
    		'title' => $sku->title,
    		'number' => $sku->number,
    		'thumb' => $sku->thumb,
    		'sku_type' => $sku->sku_type,
            'product_id' => $sku->product_id,
            'sku_id' => $sku->id,
            'sku_level' => $sku->level ?: 0,
            // 'is_free_order' => $isFreeOrder,
            'free_order_total' => $freeOrderTotal,
            'assets' => $sku->assets,
    		'total' => $total,
            'is_special_sku' => @$sku->isSpecialSku() ? 1 : 0,
            'score_price' => $sku->getSellingPrice('score'),
            'money_price' => $sku->getSellingPrice('money'),
            'pay_order_id' => @$order->id,
            'activity_id' => $package->activity_id,
            'activity_type' => $package->activity_type,
            'activity_uuid' => $package->activity_uuid,
            'node_title' => $package->title,
            'node_money_price' => $package->node_money_price,
            'node_score_price' => $package->node_score_price,
            'node_id' => $package->node_id,
            'node_type' => $package->node_type,
            'node_uuid' => $package->node_uuid,
            'open_indexs' => $sku->openIndexs,
            'open_index' => @$skuMap['open_index'] ?: $sku->openIndex,
            'options' => $sku->options,
            'source_type' => 1,     // 开盒
            'presell_date'  => $sku->presell_date,
            'room_id' => $package->room_id,
            'sku_id' => $sku->id,
            'use_lucky_score' => $sku->use_lucky_score ?: 0,
            'is_return_saleable' => is_null($sku->is_return_saleable) ? 1 : $sku->is_return_saleable
    	];

    	return new self($info);
    }

    static public function beforeGetList($options)
    {
        if (@$options['status']) {
            $options['scopes']['status'] = $options['status'];
        }

        if (@$options['sku_type']) {
            $options['scopes']['skuType'] = $options['sku_type'];
        }

        if (@$options['tag']) {
            $options['scopes']['tag'] = $options['tag'];
        }

        return $options;
    }

    // 是否可以返售
    public function isReturnSaleable()
    {
        return $this->status === 1 && $this->is_return_is_return_saleable === 1;
    }

    // 计算此sku返售金额
    public function calcReturnSaleInfo()
    {
        // 折价率
        $returnRatio = Setting::returnSaleRatio();
        $title = addslashes($this->title);
        if($this->node_type=='choushang'){
            $returnSaleRatio = DB::select("select return_sale_ratio from choushang_skus where activity_id = {$this->node_id} and title = '{$title}' ");
            if ( count($returnSaleRatio) != 0 ){
                $returnSaleRatio = object_to_array($returnSaleRatio);
                if ( isset($returnSaleRatio[0]['return_sale_ratio'])  && is_numeric($returnSaleRatio[0]['return_sale_ratio']) )
                    $returnRatio = $returnSaleRatio[0]['return_sale_ratio']?:0;
            }else{
                $returnSaleRatio = DB::select("select return_sale_ratio from choushang_last_skus where activity_id = {$this->node_id} and title = '{$title}' ");
                if ( count($returnSaleRatio) != 0 ){
                    $returnSaleRatio = object_to_array($returnSaleRatio);
                    if ( isset($returnSaleRatio[0]['return_sale_ratio']) && is_numeric($returnSaleRatio[0]['return_sale_ratio']) )
                        $returnRatio = $returnSaleRatio[0]['return_sale_ratio'];
                }
            }
        }
        if($this->node_type=='leitai'){
            $returnSaleRatio = DB::select("select return_sale_ratio from leitai_skus where activity_id = {$this->node_id} and title = '{$title}' ");
            if ( count($returnSaleRatio) != 0 ){
                $returnSaleRatio = object_to_array($returnSaleRatio);
                if ( isset($returnSaleRatio[0]['return_sale_ratio']) && is_numeric($returnSaleRatio[0]['return_sale_ratio']) )
                    $returnRatio = $returnSaleRatio[0]['return_sale_ratio'];
            }else{
                $returnSaleRatio = DB::select("select return_sale_ratio from leitai_last_skus where activity_id = {$this->node_id} and title = '{$title}' ");
                if ( count($returnSaleRatio) != 0 ){
                    $returnSaleRatio = object_to_array($returnSaleRatio);
                    if ( isset($returnSaleRatio[0]['return_sale_ratio'])  && is_numeric($returnSaleRatio[0]['return_sale_ratio']) )
                        $returnRatio = $returnSaleRatio[0]['return_sale_ratio'];
                }
            }
        }

        $money = floor($this->money_price * $this->total * $returnRatio);
        if($this->node_type=='egg_lottery'){
            $money = floor($this->node_money_price * $this->total * $returnRatio);
        }
        $redpack = 0;
        $score = floor($this->score_price * $this->total * $returnRatio);

        $moneyReturnType = Setting::returnSaleTypeForMoney();
        if ($moneyReturnType === 'money') {
            // 原路退回
        }
        elseif ($moneyReturnType === 'redpack') {
            $redpack = $money;
            $money = 0;
        }
        elseif ($moneyReturnType === 'score') {
            // 人民币兑积分比率, 每1元兑换的积分数量
            $ratio = Setting::returnMoneyToScoreRatio();
            $score += floor($money / 100 * $ratio);
            $money = 0;
        }
        
        // 打补丁，如果原路退回的金额超出订单支付金额，需要把超出的部分强制退回到红包余额
        $payOrder = $this->pay_order;

        $refundableMoney = $payOrder ? $payOrder->calcRefundableMoney() : 0;

        if ($money > $refundableMoney) {
            $diff = $money - $refundableMoney;
            $money -= $diff;
            $redpack += $diff;
        }

        return [
            $money,
            $redpack,
            $score
        ];
    }

    // 计算多个sku的返售信息
    static public function calcReturnSaleInfoForList($list)
    {
        $returnScore = 0;
        $returnMoney = 0;
        $returnRedpack = 0;

        foreach ($list as $sku) {
            list($money, $redpack, $score) = $sku->calcReturnSaleInfo();

            $returnScore += $score;
            $returnMoney += $money;
            $returnRedpack += $redpack;
        }

        return [
            $returnMoney,
            $returnRedpack,
            $returnScore
        ];
    }

    // 计算多个sku的建议转售价
    static public function calcResaleInfoForList($list)
    {
        $returnScore = 0;
        $returnMoney = 0;
        $returnRedpack = 0;

        foreach ($list as $sku) {
            list($money, $redpack, $score) = $sku->calcReturnSaleInfo();

            $returnScore += $score;
            $returnMoney += $money;
            $returnRedpack += $redpack;
        }

        return [
            $returnMoney + $returnRedpack,
            $returnScore
        ];
    }

    // 计算兑换价
    static public function calcExchangeInfoForList($list)
    {
        $returnScore = 0;
        $returnMoney = 0;
        $returnRedpack = 0;

        foreach ($list as $sku) {
            list($money, $redpack, $score) = $sku->calcReturnSaleInfo();

            $returnScore += $score;
            $returnMoney += $money;
            $returnRedpack += $redpack;
        }

        return [
            $returnMoney + $returnRedpack,
            $returnScore
        ];
    }

    // 判断是否在某个开启范围内
    public function isInOpenIndexRange($start, $end)
    {
        $flag = false;
        $openIndexs = $this->open_indexs ?: [];

        foreach ($openIndexs as $index) {
            if ($index >= $start && $index <= $end) {
                $flag = true;
                break;
            }
        }

        return  $flag;
        // return $this->
    }

    // 单个sku返售
    public function returnSale()
    {
        list($money, $redpack, $score) = $this->calcReturnSaleInfo();

        $user = $this->user;


        // 退人民币
        if ($money) {
            $order = $this->pay_order;
            $order->refund('money', $money);
        }

        // 退红包
        if ($redpack) {
            $user->asset('redpack')->in($redpack, [
                'description' => '回收'
            ]);
            // $order->refund('redpack', $redpack);
        }

        // 退积分
        if ($score) {
            $user->asset('score')->in($score, [
                'description' => '回收'
            ]);
        }

        $this->update([
            'status' => 3,
            'return_saled_at' => now(),
            'return_redpack' => $redpack,
            'return_money' => $money,
            'return_score' => $score
        ]);

        return true;
    }

    // 实物提取 (提取包含选择发货)
    public function pick($order)
    {
        // 状态不为待处理
        if ($this->union_status !== 'pending') {
            return false;
        }

        $this->update([
            'status' => 2,
            'picked_at' => now(),
            'pick_order_id' => $order->id
        ]);

        return true;
    }

    // 虚拟资产提取
    public function pickVirtualAsset()
    {
        if ($this->sku_type_text !== 'virtual_asset') {
            return false;
        }

        if ($this->union_status !== 'pending') {
            return false;
        }

        for ($i=0; $i<$this->total; $i++) {
            $res = Asset::sendTo($this->assets, $this->user, [
                'description' => '奖品提取',
                'type' => 'package_sku_pick'
            ]);
        }

        $this->update([
            'status' => 2,
            'picked_at' => now(),
            'pick_order_id' => null
        ]);

        return $res;
    }

    // 
    public function tryAutoPick()
    {
        // 领取虚拟奖品
        $this->pickVirtualAsset();

        // 领取免单
        if ($this->sku_type === 5) {

            if ($this->node_money_price) {
                $this->user->asset('redpack')->in($this->node_money_price, [
                    'description' => '活动免单-' . $this->node_title
                ]);
            }

            if ($this->node_score_price) {
                $this->user->asset('score')->in($this->node_score_price, [
                    'description' => '活动免单-' . $this->node_title
                ]);
            }

            $this->update([
                'status' => 2,
                'picked_at' => now(),
                'pick_order_id' => null
            ]);
        }
    }


    // 撤回物品仓库
    public function resetToPending()
    {
        $this->update([
            'status' => 1
        ]);
    }

    // 生成转售
    public function createResale($moneyPrice, $scorePrice, $optoins =  [])
    {

        if ($this->union_status !== 'pending') {
            return false;
        }

        // 生成转售记录
        $record = Resale::create([
            'user_id' => $this->user_id,
            'package_sku_id' => $this->id,
            'resale_type' => 'package_sku',
            'product_total' => $this->total,
            'money_price' => $moneyPrice,
            'score_price' => $scorePrice,
            'limit_phone' => @$optoins['limit_phone'],
            'is_allow_fast_match' => $optoins['is_allow_fast_match']
        ]);

        $record->generateSid();

        $record->package_skus()->sync([$this->id]);

        $this->update([
        	'resale_id' => $record->id,
            'status' => 5
        ]);

        return $record;
    }

    // 以建议价生成自动匹配的快速转售
    public function createAutoMatchResale()
    {
        list($money, $redpack, $score) = $this->calcReturnSaleInfo();
        $money = $money + $redpack;

        return $this->createResale($money, $score, [
            'is_allow_fast_match' => 1
        ]);
    }

    // 取消转售
    public function cancelResale()
    {
        $this->update([
            'status' => 1
        ]);
    }

    // 发货时价格为0
    public function getSellingPrice($type = 'money', $options = [])
    {
        return 0;
    }

    // 完成转售
    public function completeResale($resale, $order)
    {
        $info = $this->getInfo([
            'title',
            'number',
            'thumb',
            'sku_type',
            'product_id',
            'assets',
            'total',
            'score_price',
            'money_price',
            'activity_id',
            'activity_type',
            'open_index',
            'open_indexs',
            'options',
            'is_return_saleable',
            'is_giveable',
            'room_id',
            'activity_id',
            'activity_type',
            'activity_uuid',
            'node_type',
            'node_id',
            'node_uuid',
            'node_title',
            'node_money_price',
            'node_score_price'
        ]);

        $info = array_merge($info, [
            'uuid' => uniqid(),
            'user_id' => $resale->buyer_id,
            'pay_order_id' => @$order->id,
            'source_type' => 2,
            'from_package_sku_id' => $this->id
        ]);

        // \Log::error($info);

        // 创建复制品给买方用户
        $newPackageSku = self::create($info);

        // 标记为已转售
        $this->update([
            'status' =>  4,
            'resaled_at' => now()
        ]);
    }

    // 完成转售
    public function completeResaleForTenant($resale, $order)
    {
        // 标记为已转售
        $this->update([
            'status' =>  4,
            'resaled_at' => now()
        ]);
    }

    // 转化为orderSku
    public function generateSkuInfo()
    {
        $options = [];

        $payOrder = $this->pay_order;

        $info = [
            'sku_id' => $this->id,
            'sku_uuid' => $this->uuid,
            'base_sku_type' => $this->getType('base_sku_type'),
            'sku_type' => $this->sku_type,
            // 'is_hidden_sku' => 0,
            'activity_id' => @$this->activity_id,
            'activity_uuid' => @$this->activity_uuid,
            'activity_type' => @$this->activity_type,
            'node_id' => @$this->node_id,
            'node_uuid' => @$this->node_uuid,
            'node_type' => @$this->node_type,
            'title' => $this->title,
            'thumb' => $this->thumb,
            'number' => $this->number,
            // 'group_price_title' => @$groupPrice->title,
            'attrs' => @$this->attrs ?: [],
            'money_price' => $this->getOriginalPrice('money'),
            'discount_money_price' => $this->getSellingPrice('money', $options),
            'score_price' => $this->getOriginalPrice('score'),
            'discount_score_price' => $this->getSellingPrice('score', $options),
            'pay_order_id' => @$payOrder->id,
            'pay_order_number' => @$payOrder->number,
            'sku_assets' => $this->assets,
            'options' => $this->options
        ];

        return $info;
    }
}
